from hashlib import md5
from json import dumps
from os import remove
from api.db import Database

class UserOpe:
    """
    用户相关操作的接口
    """
    SALT = "软工管第七组" 

    def __init__(self):
        self.md5 = md5()
        self.db = Database()
    def user_login(self, username, password) -> bool:
        """
        用户登录，检查密码是否正确
        :return: True or False
        """
        pwd = self.db.query_user(username)
        if not pwd:
            return False
        pwd = pwd[0]['password']
        password += self.SALT
        self.md5 = md5()
        self.md5.update(password.encode('utf-8'))
        if self.md5.hexdigest() == pwd:
            return True
        else:
            return False
    def user_register(self, username, password, secure_question, secure_answer, isAdmin=False) -> bool:
        """
        用户注册，检查用户名是否已存在
        :param username: 用户名
        :param password: 密码
        :param secure_question: 密保问题
        :param secure_answer: 密保答案
        :param isAdmin: 是否为管理员
        :return:
        """
        if self.db.query_user(username):
            return False
        password += self.SALT
        self.md5 = md5()
        self.md5.update(password.encode('utf-8'))
        self.db.add_user(username, self.md5.hexdigest(), isAdmin, secure_question, secure_answer)
        return True
    def get_user(self, username) -> str:
        """
        获取用户信息
        :param username: 用户名
        :return: json 格式的用户信息
        """
        user = self.db.query_user(username)
        if user:
            return dumps(user[0])
        return ''
    def get_secure_question(self, username) -> str:
        """
        获得密保问题
        """
        user = self.get_user(username)
        if user:
            return user['secure_question']
        return ''
    def check_secure_answer(self, username, secure_answer) -> bool:
        """
        检查密保答案
        :param username: 用户名
        :param secure_answer: 密保答案
        :return: True or False
        """
        user = self.get_user(username)
        if user:
            return user['secure_answer'] == secure_answer
        return False
    def delete_user(self, username) -> None:
        """
        删除用户
        :param username: 用户名
        :return:
        """
        self.db.delete_user(username)
    def update_user(self, username, password) -> None:
        """
        更新用户信息
        :param username: 用户名
        :param password: 密码
        :return:
        """
        self.md5.update(password.encode('utf-8'))
        self.db.update_user(username, self.md5.hexdigest())
    
class ArticleOpe:
    """
    文章相关操作的接口
    """
    def __init__(self):
        self.db = Database()
    def get_article(self, article_id) -> str:
        """
        获取文章信息
        :param article_id: 文章id
        :return: json 格式的文章信息
        """
        article = self.db.query_article(article_id)
        if article:
            return dumps(article[0])
        return ''
    def get_all_articles(self, course) -> str:
        """
        获取所有文章
        :param course: 课程名
        :return: json 格式的文章列表
        """
        return dumps(self.db.query_all_articles(course))
    def add_article(self, path, course, uploader, title) -> None:
        """
        添加文章
        :param path: 文章路径
        :param course: 课程名
        :param uploader: 上传者
        :param title: 文章标题
        :return:
        """
        self.db.add_article(path, course, uploader, title)
    def update_article(self, id, course, uploader, title) -> None:
        """
        更新文章信息
        :param id: 文章id
        :param course: 课程名
        :param uploader: 上传者
        :param title: 文章标题
        :return:
        """
        self.db.update_article(id, course, uploader, title)
    def hide_article(self, id) -> None:
        """
        隐藏文章，但不删除本地文件
        :param id: 文章id
        :return:
        """
        self.db.delete_article(id)
    def delete_article(self, id) -> None:
        """
        删除文章，同时删除本地文件
        :param id: 文章id
        :return:
        """
        path = self.get_article_path(id)
        self.db.delete_article(id)
        if path:
            remove(path)
    def get_user_articles(self, username) -> str:
        """
        获取用户上传的所有文章
        :param username: 用户名
        :return: json 格式的文章列表
        """
        return dumps(self.db.query_user_articles(username))

class CourseOpe:
    """
    课程相关操作的接口
    """
    def __init__(self):
        self.db = Database()
    def get_course_path(self, course) -> str:
        """
        获取课程文件路径
        :return: 文件路径
        """
        path = self.db.query_course(course)
        if path:
            return dumps(path[0]['path'])
        return ''
    def add_course(self, course, path) -> None:
        """
        添加课程
        :param course: 课程名
        :return:
        """
        self.db.add_course(course, path)
    def hide_course(self, course) -> None:
        """
        隐藏课程，但不删除文件
        :param course: 课程名
        :return:
        """
        self.db.delete_course(course)
    def delete_course(self, course) -> None:
        """
        删除课程，同时删除文件
        :param course: 课程名
        :return:
        """
        path = self.get_course_path(course)
        self.db.delete_course(course)
        if path:
            remove(path)

class CommentOpe:
    """
    评论相关操作的接口
    """
    def __init__(self):
        self.db = Database()
    def add_comment(self, course, username, content) -> None:
        """
        添加评论
        :param course: 课程名称
        :param username: 用户名
        :param content: 评论内容
        :return:
        """
        self.db.add_comment(course, username, content)
    def get_comment(self, id) -> str:
        """
        获取评论
        :param id: 评论id
        :return: json 格式的评论信息
        """
        comment = self.db.query_comment(id)
        if comment:
            return dumps(comment[0], default=str)
        return ''
    def get_all_comments(self, course) -> str:
        """
        获取评论
        :param course: 课程名称
        :return: json 格式的评论列表
        """
        return dumps(self.db.query_course_comments(course), default=str)
    def get_user_all_comments(self, username) -> str:
        """
        获取用户所有评论
        :param username: 用户名
        :return: json 格式的评论列表
        """
        return dumps(self.db.query_user_comments(username), default=str)
    def update_comment(self, id, content) -> None:
        """
        更新评论
        :param id: 评论id
        :param content: 评论内容
        :return:
        """
        self.db.update_comment(id, content)
    def delete_comment(self, id) -> None:
        """
        删除评论
        :param id: 评论id
        :return:
        """
        self.db.delete_comment(id)

class ScoreOpe:
    """
    打分相关操作的接口
    """
    def __init__(self):
        self.db = Database()
    def add_score(self, id, username, score) -> None:
        """
        添加打分
        :param id: 文章id
        :param username: 用户名
        :param score: 打分
        :return:
        """
        self.db.add_score(id, username, score)
    def get_avg_score(self, id) -> str:
        """
        获取文章平均分
        :param id: 文章id
        :return: 平均分
        """
        all_score = self.db.query_article_scores(id)
        avg_score = 0
        if all_score:
            for i in all_score:
                avg_score += i['score']
            avg_score /= len(all_score)
            return dumps({'avg_score': avg_score, 'count': len(all_score)})
        return ''
    def get_user_article_score(self, id, username) -> int:
        """
        获取用户对文章的打分
        :param id: 文章id
        :param username: 用户名
        :return: 打分
        """
        score = self.db.query_user_article_score(id, username)
        if score:
            return int(score[0]['score'])
        return ''
    def get_user_all_scores(self, username) -> str:
        """
        获取用户所有打分
        :param username: 用户名
        :return: json 格式的打分列表
        """
        return dumps(self.db.query_user_scores(username))
    def update_score(self, id, username, score) -> None:
        """
        更新打分
        :param id: 文章id
        :param username: 用户名
        :param score: 打分
        :return:
        """
        self.db.update_score(id, username, score)
    def delete_score(self, id, username) -> None:
        """
        删除打分
        :param id: 文章id
        :param username: 用户名
        :return:
        """
        self.db.delete_score(id, username)
class VoteOpe:
    """
    投票相关操作的接口
    """
    def __init__(self):
        self.db = Database()
    def vote(self, id, username, vote) -> None:
        """
        添加投票
        :param id: 评论id
        :param username: 用户名
        :param vote: 投票
        :return:
        """
        self.delete_vote(id, username)
        if vote:
            self.db.like_comment(id, username)
        else:
            self.db.dislike_comment(id, username)
    def get_comment_vote(self, id, username) -> bool:
        """
        获取用户对评论的投票
        :param id: 评论id
        :param username: 用户名
        :return: 投票
        """
        vote = self.db.query_user_votes(id, username)
        if vote:
            return bool(vote[0]['condition'])
        return None
    def delete_vote(self, id, username) -> None:
        """
        删除投票
        :param id: 评论id
        :param username: 用户名
        :return:
        """
        result = self.db.query_comment_vote(id, username)
        if result is not None:
            if result:
                self.db.delete_like(id, username)
            else:
                self.db.delete_dislike(id, username)
    def get_all_votes(self, username) -> int:
        """
        获取用户所有赞
        :param username: 用户名
        :return: 赞数
        """
        comments = self.db.query_user_comments(username)
        count = 0
        for i in comments:
            count += i['likes']
        return count

if __name__ == '__main__':
    # user = UserOpe()
    # user.delete_user('admin')
    # user.delete_user('user')
    # print(user.user_register('admin', 'admin', '', '', True))
    # print(user.user_login('admin', 'admin'))
    # user.user_register('user', 'user', '', '')
    # print(user.get_user('admin'))
    # course = CourseOpe()
    # course.hide_course('test')
    # course.add_course('test', 'path/to/test.md')
    # print(course.get_course_path('test'))
    comment = CommentOpe()
    # comment.add_comment('test', 'admin', 'test')
    # comment.add_comment('test', 'user', 'test123')
    # print(comment.get_all_comments('test'))
    # print(comment.get_user_all_comments('admin'))
    # comment.update_comment(11, 'test456')
    # print(comment.get_comment(11))
    # score = ScoreOpe()
    # art = ArticleOpe()
    # art.add_article('path/to/article.md', 'test', 'admin')
    # score.add_score(1, 'admin', 5)
    # score.add_score(1, 'user', 4)
    # print(score.get_avg_score(1))
    # print(score.get_user_article_score(1, 'admin'))
    # print(score.get_user_all_scores('admin'))
    # score.update_score(1, 'admin', 3)
    # print(score.get_avg_score(1))
    # print(score.get_user_article_score(1, 'admin'))
    # score.delete_score(1, 'admin')
    # print(score.get_avg_score(1))
    # print(score.get_user_article_score(1, 'admin'))
    vote = VoteOpe()
    # vote.vote(6, 'admin', True)
    # vote.vote(6, 'user', False)
    # print(vote.get_comment_vote(6, 'admin'))
    # print(comment.get_comment(6))
    vote.vote(6, 'admin', True)
    print(comment.get_comment(6))
    pass